package com.zhou.bjgl.bjgl.business_web.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhou.bjgl.bjgl.business_web.entity.BHoliday;
import com.zhou.bjgl.bjgl.exception.BwException;
import com.zhou.bjgl.bjgl.exception.BwExceptionEnum;
import com.zhou.bjgl.bjgl.business_web.mapper.BHolidayMapper;
import com.zhou.bjgl.bjgl.req.b_holiday.BHlidayChartsReq;
import com.zhou.bjgl.bjgl.req.b_holiday.BHolidayQueryReq;
import com.zhou.bjgl.bjgl.req.b_sign.BSigningChartsReq;
import com.zhou.bjgl.bjgl.resp.BHolidayResp;
import com.zhou.bjgl.bjgl.resp.PageResp;
import com.zhou.bjgl.bjgl.business_web.service.BHolidaySerivce;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhou.bjgl.bjgl.util.CopyUtil;
import com.zhou.bjgl.bjgl.util.DateUtil;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  请假servcie实现类
 * </p>
 *
 * @author jz
 * @since 2021-07-04
 */
@Service
public class BHolidayServiceImpl extends ServiceImpl<BHolidayMapper, BHoliday> implements BHolidaySerivce {

    @Resource
    private BHolidayMapper bHolidayMapper;


    /**
     * 申请请假
     * @param req
     */
    @Override
    public void apply(BHolidayQueryReq req) {
        BHoliday bHoliday = CopyUtil.copy(req, BHoliday.class);
        bHolidayMapper.insert(bHoliday);
    }

    /**
     * 获取请假列表
     * @param req
     * @return
     */
    @Override
    public PageResp<BHolidayResp> listholidayApply(BHolidayQueryReq req) {

        //进行分页查询
        PageHelper.startPage(req.getPage(),req.getSize());
        List<BHolidayResp> bHolidayResps=bHolidayMapper.queryHolidayApply(req);

        //构造返回结果
        PageInfo<BHolidayResp> pageInfo = new PageInfo<>(bHolidayResps);
        PageResp<BHolidayResp> pageRespForHoliday = new PageResp<>();
        pageRespForHoliday.setTotal(pageInfo.getTotal());
        pageRespForHoliday.setPageList(bHolidayResps);
        return pageRespForHoliday;
    }

    /**
     * 进行核验销假
     * @param req
     */
    @Override
    public void check(BHolidayQueryReq req) {
        BHoliday bHoliday = bHolidayMapper.selectById(req.getId());
        if (bHoliday == null) {
            throw new BwException(BwExceptionEnum.IS_NULL);
        }
        Double latitudeInApply = bHoliday.getLatitude();
        Double longitudeInApply = bHoliday.getLongitude();

        //构造两个地理坐标点
        GlobalCoordinates source = new GlobalCoordinates(latitudeInApply, longitudeInApply);
        GlobalCoordinates target = new GlobalCoordinates(req.getLatitude(), req.getLongitude());

        //传入两个坐标和距离计算方式
        double distanceMeter = getDistanceMeter(source, target, Ellipsoid.Sphere);
        //如果距离打开地点远于1000m，打卡失败
        if (distanceMeter > 500) {
            throw new BwException(BwExceptionEnum.OUT_OF_POSITION);
        }

        //打卡成功之后设置打卡成功
        BHoliday newBHoliday = new BHoliday();
        newBHoliday.setChecked(1);
        newBHoliday.setId(req.getId());
        bHolidayMapper.updateById(newBHoliday);
    }

    @Override
    public void checkBack(BHolidayQueryReq req) {
        BHoliday bHoliday = bHolidayMapper.selectById(req.getId());
        if (bHoliday == null) {
            throw new BwException(BwExceptionEnum.IS_NULL);
        }
        Double latitudeInApply = bHoliday.getBackLatitude();
        Double longitudeInApply = bHoliday.getBackLongitude();

        //构造两个地理坐标点
        GlobalCoordinates source = new GlobalCoordinates(latitudeInApply, longitudeInApply);
        GlobalCoordinates target = new GlobalCoordinates(req.getBackLatitude(), req.getBackLongitude());

        //传入两个坐标和距离计算方式
        double distanceMeter = getDistanceMeter(source, target, Ellipsoid.Sphere);
        //如果距离打开地点远于100m，打卡失败
        if (distanceMeter > 500) {
            throw new BwException(BwExceptionEnum.NOT_ARRIVED_BACK);
        }

        //打卡成功之后设置打卡成功
        BHoliday newBHoliday = new BHoliday();
        newBHoliday.setChecked(3);
        newBHoliday.setId(req.getId());
        bHolidayMapper.updateById(newBHoliday);
    }

    @Override
    public HashMap<String, List> queryHolidayChartData(BHlidayChartsReq bHlidayChartsReq) {
        //用于存储每个所需字段的的数据
        HashMap<String, List> rsultMap = new HashMap<>(4);
        //获取所有日期
        List<String> betweenDate;
        if (ObjectUtils.isEmpty(bHlidayChartsReq.getStartDate())) {
            betweenDate = DateUtil.getLastWeek();
        } else {
            betweenDate = DateUtil.getBetweenDate(bHlidayChartsReq.getStartDate(), bHlidayChartsReq.getEndDate());
        }

        rsultMap.put("dateList",betweenDate);
        //构建查询对象
        BHlidayChartsReq bHlidayChartsReqQuery = new BHlidayChartsReq();
        bHlidayChartsReqQuery.setClassId(bHlidayChartsReq.getClassId());
        //遍历每个日期的数据
        ArrayList<Integer> resultCountList = new ArrayList<>();
        for (String date:
                betweenDate) {
            bHlidayChartsReqQuery.setStartDate(date);
            int count=bHolidayMapper.queryNotCheckForDate(bHlidayChartsReqQuery);
            resultCountList.add(count);
        }
        //用于存储每个所需字段的的数据
        rsultMap.put("countList", resultCountList);
        return rsultMap;
    }

    /**
     * 计算两点之间距离的方法
     * @param gpsFrom
     * @param gpsTo
     * @param ellipsoid
     * @return
     */
    public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid)
    {
        //创建GeodeticCalculator，调用计算方法，传入坐标系、经纬度用于计算距离
        GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo);

        return geoCurve.getEllipsoidalDistance();
    }
}
